﻿//
//                       _oo0oo_
//                      o8888888o
//                      88" . "88
//                      (| -_- |)
//                      0\  =  /0
//                    ___/`---'\___
//                  .' \\|     |// '.
//                 / \\|||  :  |||// \
//                / _||||| -:- |||||- \
//               |   | \\\  -  /// |   |
//               | \_|  ''\---/''  |_/ |
//               \  .-\__  '-'  ___/-. /
//             ___'. .'  /--.--\  `. .'___
//          ."" '<  `.___\_<|>_/___.' >' "".
//         | | :  `- \`.;`\ _ /`;.`/ - ` : | |
//         \  \ `_.   \_ __\ /__ _/   .-` /  /
//     =====`-.____`.___ \_____/___.-`___.-'=====
//                       `=---='
//
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
//               佛祖保佑         永无BUG
//
//     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#region << 版 本 注 释 >>

/*----------------------------------------------------------------
* 类 名 称 ：NodeAction
* 类 描 述 ：
* 作    者 ：henrychang
* 创建时间 ：2019/1/11 14:10:57
*******************************************************************
* Copyright @ henrychang 2018. All rights reserved.
*******************************************************************
//----------------------------------------------------------------*/

#endregion << 版 本 注 释 >>

using System;

namespace TouchFish.NodeActionSystem
{
    /// <summary>
    /// 执行节点的基类
    /// </summary>
    public abstract class NodeAction : IAction
    {
        /// <summary>
        /// 节点开始回调
        /// </summary>
        public Action OnBeganCallback = null;

        /// <summary>
        /// 节点结束回调
        /// </summary>
        public Action OnEndedCallback = null;

        /// <summary>
        /// 节点释放回调
        /// </summary>
        public Action OnDisposedCallback = null;

        protected bool mOnBeginCalled = false;

        #region IAction Support

        bool IAction.Disposed
        {
            get { return mDisposed; }
        }

        protected bool mDisposed = false;

        public bool Finished { get; protected set; }

        public virtual void Finish()
        {
            Finished = true;
            OnEndedCallback.InvokeGracefully();
            OnEnd();
        }

        public void Break()
        {
            Finished = true;
        }

        #endregion IAction Support

        #region ResetableSupport

        public void Reset()
        {
            Finished = false;
            mOnBeginCalled = false;
            mDisposed = false;
            OnReset();
        }

        #endregion ResetableSupport

        #region IExecutable Support

        /// <summary>
        /// 节点执行
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public bool Execute()
        {
            // 有可能被别的地方调用
            if (Finished)
            {
                return Finished;
            }

            if (!mOnBeginCalled)
            {
                mOnBeginCalled = true;
                OnBegin();
                OnBeganCallback.InvokeGracefully();
            }

            if (!Finished)
            {
                OnExecute();
            }

            if (Finished)
            {
                Finish();
            }

            return Finished || mDisposed;
        }

        #endregion IExecutable Support

        protected virtual void OnReset()
        {
        }

        protected virtual void OnBegin()
        {
        }

        /// <summary>
        /// finished
        /// </summary>
        protected virtual void OnExecute()
        {
        }

        protected virtual void OnEnd()
        {
        }

        protected virtual void OnDispose()
        {
        }

        #region IDisposable Support

        public void Dispose()
        {
            if (mDisposed) return;
            mDisposed = true;

            OnBeganCallback = null;
            OnEndedCallback = null;
            OnDisposedCallback.InvokeGracefully();
            OnDisposedCallback = null;
            OnDispose();
        }

        #endregion IDisposable Support
    }
}